﻿using System;
using System.Web;

using NCT.Framework;
using VISS.API.Users;
using VISS.API.Commons;

namespace VISS.Web.Frontend {
    /// <summary>
    /// Dùng cho các hàm login của FronEnd
    /// </summary>
    public class LoginFactory {
        protected const string LOGIN_COOKIE = "LoginFactoryCookie";
        protected const string LOGIN_SESSION = "UserSCEnt";

        /// <summary>
        /// Thoát khỏi hệ thống, xóa session và cookie
        /// </summary>
        public static void Logout() {
            RemoveUserSession();
            RemoveUserCookie();
        }

        /// <summary>
        /// Cập nhật lại đường dẫn file Avatar
        /// </summary>
        /// <param name="userKey"></param>
        /// <param name="gender"></param>
        /// <returns></returns>
        public static string RefeshAvatarPath(string userKey, EUserGender gender) {
            IUserAvatar iUserAvatar = StructureMapFactory.GetInstance<IUserAvatar>();
            UserAvatarEnt userAvatarEnt = iUserAvatar.GetByUserKey(userKey);
            if (userAvatarEnt != null && userAvatarEnt.Status == EUserAvatarStatus.Available)
                return AppSettings.ImageStoreUploadServer + userAvatarEnt.FileName + "?" + NumberUtils.GetRandomNum(0, 2010);
            else {
                if (gender == EUserGender.Male) {
                    return AppSettings.AvatarMLargeBlank;
                }
                else {
                    return AppSettings.AvatarFLargeBlank;
                }
            }
        }

        /// <summary>
        /// Cập nhật lại đường dẫn file Avatar-Thumb
        /// </summary>
        /// <param name="userKey"></param>
        /// <param name="gender"></param>
        /// <returns></returns>
        public static string RefeshAvatarThumbPath(string userKey, EUserGender gender) {
            IUserAvatar iUserAvatar = StructureMapFactory.GetInstance<IUserAvatar>();
            UserAvatarEnt userAvatarEnt = iUserAvatar.GetByUserKey(userKey);
            if (userAvatarEnt != null && userAvatarEnt.Status == EUserAvatarStatus.Available) {
                int indexOfDot = userAvatarEnt.FileName.LastIndexOf(".");
                string avatarThumbFileName = userAvatarEnt.FileName.Substring(0, indexOfDot) + "-thumb" + userAvatarEnt.FileName.Substring(indexOfDot);

                return AppSettings.ImageStoreUploadServer + avatarThumbFileName + "?" + NumberUtils.GetRandomNum(0, 2010);
            }
            else {
                if (gender == EUserGender.Male) {
                    return AppSettings.AvatarMSmallBlank;
                }
                else {
                    return AppSettings.AvatarFSmallBlank;
                }
            }
        }

        /// <summary>
        /// hàm đăng nhập dung OpenID, out ra thông tin thành viên.
        /// </summary>
        /// <param name="userName"></param>
        /// <param name="password"></param>
        /// <param name="setCookie"></param>
        /// <param name="userSC"></param>
        /// <returns></returns>
        public static EUserLoginResult LoginOpenID(string email, bool setCookie, out UserContext userSC) {
            EUserLoginResult result;
            try {
                IUser userBC = StructureMapFactory.GetInstance<IUser>();
                UserEnt objUser = null;
                //if (checkPass)
                //{
                // log: trường hợp kiểm tra mật khẩu.
                //_log.LoginAsyn(Commons.GetClientIP(), HttpContext.Current.Session.SessionID, userName, true);

                result = userBC.OpenIDLogin(email, out objUser);
                if (result == EUserLoginResult.Success) {
                    IUserGeneralProfile iUserGeneralProfile = StructureMapFactory.GetInstance<IUserGeneralProfile>();
                    UserGeneralProfileEnt userGeneralProfileEnt = iUserGeneralProfile.GetByUserKey(objUser.UserKey);
                    userSC = new UserContext(objUser.ID, 
                                            objUser.UserKey, 
                                            objUser.Email, 
                                            userGeneralProfileEnt.Name, 
                                            objUser.Status, 
                                            objUser.DateCreated, 
                                            RefeshAvatarPath(objUser.UserKey, userGeneralProfileEnt.Gender), 
                                            userGeneralProfileEnt.Gender,
                                            userGeneralProfileEnt.LookingFor);
                    SetUserSession(userSC);
                    SetUserCookie(userSC.Email, setCookie);
                }
                else {
                    userSC = null;
                }
            }
            catch (Exception ex) {
                throw ex;
            }

            return result;
        }

        /// <summary>
        /// hàm đăng nhập, out ra thông tin thành viên.
        /// </summary>
        /// <param name="userName"></param>
        /// <param name="password"></param>
        /// <param name="setCookie"></param>
        /// <param name="userSC"></param>
        /// <returns></returns>
        public static EUserLoginResult Login(string email, string password, bool setCookie, out UserContext userSC) {
            EUserLoginResult result;
            try {
                IUser userBC = StructureMapFactory.GetInstance<IUser>();
                UserEnt objUser = null;

                result = userBC.Login(email, password, out objUser);
                if (result == EUserLoginResult.Success) {
                    IUserGeneralProfile iUserGeneralProfile = StructureMapFactory.GetInstance<IUserGeneralProfile>();
                    UserGeneralProfileEnt userGeneralProfileEnt = iUserGeneralProfile.GetByUserKey(objUser.UserKey);
                    userSC = new UserContext(objUser.ID,
                                            objUser.UserKey,
                                            objUser.Email,
                                            userGeneralProfileEnt.Name,
                                            objUser.Status,
                                            objUser.DateCreated,
                                            RefeshAvatarPath(objUser.UserKey, userGeneralProfileEnt.Gender),
                                            userGeneralProfileEnt.Gender,
                                            userGeneralProfileEnt.LookingFor);
                    SetUserSession(userSC);
                    SetUserCookie(userSC.Email, setCookie);
                }
                else {
                    userSC = null;
                }
            }
            catch (Exception ex) {
                userSC = null;
                result = EUserLoginResult.Unknown;
                LogUtils.Error(string.Format("VISS.Web.Frontend.LoginFactory.Login({0}, {1}, {2})" + ex.Message, email, password, setCookie));
            }
            return result;
        }

        /// <summary>
        /// lưu thông tin nhớ tài khoản thông qua cookie.
        /// </summary>
        /// <param name="userName"></param>
        /// <param name="checkCookie"></param>
        public static void SetUserCookie(string userName, bool checkCookie) {
            HttpCookie cookie = new HttpCookie(LOGIN_COOKIE);
            string usernameEncrypt = ConvertUtils.RijndaelEncrypt2Hex(userName, AppSettings.EncryptKeyCookie);
            cookie[LOGIN_SESSION] = usernameEncrypt;
            if (checkCookie)
                cookie.Expires = DateTime.Now.AddDays(30);  // có checked nhớ tài khoản, lưu cookie trong 30 ngày.
            else
                cookie.Expires = DateTime.Now.AddDays(7);   // không checked nhớ tài khoản, lưu cookie trong 7 ngày.
            HttpContext.Current.Response.Cookies.Add(cookie);
        }

        /// <summary>
        /// hủy lưu cookie.
        /// </summary>
        public static void RemoveUserCookie() {
            HttpCookie cookie = HttpContext.Current.Request.Cookies[LOGIN_COOKIE];
            if (cookie != null) {
                cookie.Values.Clear();
                cookie.Expires = DateTime.Now.AddDays(-1);
                HttpContext.Current.Response.Cookies.Add(cookie);
            }
        }

        /// <summary>
        /// lưu session đăng nhập.
        /// </summary>
        /// <param name="userSC"></param>
        public static void SetUserSession(UserContext userSC) {
            HttpContext.Current.Session[LOGIN_SESSION] = userSC;
        }

        /// <summary>
        /// hủy session đăng nhập.
        /// </summary>
        public static void RemoveUserSession() {
            HttpContext.Current.Session.Remove(LOGIN_SESSION);
        }

        /// <summary>
        /// lấy lại thông tin user, nếu không có session thì kiểm tra cookie để stored lại session đăng nhập cho user đó.
        /// </summary>
        /// <returns></returns>
        public static UserContext GetCurrentUser() {
            if (HttpContext.Current.Session == null)
                return null; // nếu không có session

            UserContext userContext = HttpContext.Current.Session[LOGIN_SESSION] as UserContext;

            if (userContext == null) {
                HttpCookie cookie = HttpContext.Current.Request.Cookies[LOGIN_COOKIE];

                if (cookie != null && cookie[LOGIN_SESSION] != null) {
                    string cipherUser = ConvertUtils.ToString(cookie[LOGIN_SESSION]);
                    try {
                        // mã hóa tên đăng nhập trước khi lưu cookie.
                        cipherUser = ConvertUtils.RijndaelDecryptFromHex(cipherUser, AppSettings.EncryptKeyCookie);
                        cipherUser = cipherUser.Trim('\0');
                    }
                    catch {
                        RemoveUserCookie();
                        return null;
                    }

                    userContext = new UserContext();
                    EUserLoginResult result = LoginOpenID(cipherUser, false, out userContext);

                    if (result == EUserLoginResult.Success) {
                        SetUserSession(userContext);
                    }
                    else {
                        userContext = null;
                    }
                }
            }

            return userContext;
        }

        /// <summary>
        /// Lấy email đăng nhập của người dùng
        /// </summary>
        /// <returns></returns>
        public static string GetCurrentUserEmail() {
            UserContext userContext = GetCurrentUser();
            if (userContext != null) {
                return userContext.Email;
            }
            else {
                return "";
            }
        }

    }
}
